﻿using System.Configuration;

namespace Pixeldyne.Core.Configuration
{
	/// <summary>
	/// Represents a configuration element containing a collection of child elements.
	/// </summary>
	/// <typeparam name="TKeyObjectType"></typeparam>
	/// <typeparam name="TValueObjectType"></typeparam>
	public abstract class BaseCollection<TKeyObjectType, TValueObjectType> :
		ConfigurationElementCollection where TValueObjectType : ConfigurationElement, new()
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="BaseCollection&lt;TKeyObjectType, TValueObjectType&gt;"/> class.
		/// </summary>
		protected BaseCollection()
		{
		}

		/// <summary>
		/// Gets the type of the collection.
		/// </summary>
		/// <value>The type of the collection.</value>
		public override ConfigurationElementCollectionType CollectionType
		{
			get
			{
				return ConfigurationElementCollectionType.AddRemoveClearMap;
			}
		}

		/// <summary>
		/// Gets the name used to identify this collection of elements in the configuration file when overridden in a derived class.
		/// </summary>
		/// <value></value>
		/// <returns>
		/// The name of the collection; otherwise, an empty string. The default is an empty string.
		/// </returns>
		protected override string ElementName
		{
			get
			{
				return string.Empty;
			}
		}

		/// <summary>
		/// When overridden in a derived class, creates a new <see cref="T:System.Configuration.ConfigurationElement"/>.
		/// </summary>
		/// <returns>
		/// A new <see cref="T:System.Configuration.ConfigurationElement"/>.
		/// </returns>
		protected override ConfigurationElement CreateNewElement()
		{
			return new TValueObjectType();
		}

		/// <summary>
		/// Gets the element key for a specified configuration element when overridden in a derived class.
		/// </summary>
		/// <param name="element">The <see cref="T:System.Configuration.ConfigurationElement"/> to return the key for.</param>
		/// <returns>
		/// An <see cref="T:System.Object"/> that acts as the key for the specified <see cref="T:System.Configuration.ConfigurationElement"/>.
		/// </returns>
		protected override object GetElementKey(ConfigurationElement element)
		{
			return GetElementKey((TValueObjectType)element);
		}

		/// <summary>
		/// Gets the element key.
		/// </summary>
		/// <param name="element">The element.</param>
		/// <returns></returns>
		protected abstract TKeyObjectType GetElementKey(TValueObjectType element);

		/// <summary>
		/// Adds the specified path.
		/// </summary>
		/// <param name="path">The path.</param>
		public void Add(TValueObjectType path)
		{
			BaseAdd(path);
		}

		/// <summary>
		/// Removes the specified key.
		/// </summary>
		/// <param name="key">The key.</param>
		public void Remove(TKeyObjectType key)
		{
			BaseRemove(key);
		}

		/// <summary>
		/// Gets the value with the specified key.
		/// </summary>
		/// <value></value>
		public TValueObjectType this[TKeyObjectType key]
		{
			get { return (TValueObjectType)BaseGet(key); }
		}

		/// <summary>
		/// Gets the value at the specified index.
		/// </summary>
		/// <value></value>
		public TValueObjectType this[int index]
		{
			get { return (TValueObjectType)BaseGet(index); }
		}

		/// <summary>
		/// Determines whether the collection contains the specified value.
		/// </summary>
		/// <param name="value">The value.</param>
		/// <returns>
		/// 	<c>true</c> if the collection contains the specified value; otherwise, <c>false</c>.
		/// </returns>
		public bool Contains(string value)
		{
			if (BaseGet(value) != null)
				return true;
			else
				return false;
		}
	}
}
